/*ShowFindUpdate*/
/*Class contain method for implementing show, find, and update*/

#include "ShowFindUpdate.h"

using namespace std;

ShowFindUpdate::ShowFindUpdate() //default constructor
{
}

// Function : Comparator for the sort function
// Type	: Support Function
// PIC : Archie
// Status : Complete
bool ChefComparator (Recipe i,Recipe j) { return (i.getChefName().compare(j.getChefName()) < 0) ;}

// Function : 1b. print all menu items sorted by Chef [print item name, ID and Price]
// Type	: Main Function
// PIC : Archie
// Status : Complete
void ShowFindUpdate::PrintMenuItemChef(vector<Menu_item> TheMIVector, vector<Recipe> TheRecipeVector)
{
	//Sort the Recipe Vector by Chef Name
	sort (TheRecipeVector.begin(), TheRecipeVector.end(), ChefComparator);

	//Print the vector
	cout << "Menu items sorted by Chef [print item name, ID and Price]\n\n";
	for(int i = 0; i < TheRecipeVector.size();i++)
	{
		//get the appropriate data
		int RecipeTemp = TheRecipeVector[i].getRecipeId(); //get recipe id
		string RecipeNameTemp = MenuItemRec_IdToName(TheMIVector,RecipeTemp);
		double RecipePriceTemp = MenuItemRec_IdToPrice(TheMIVector,RecipeTemp);
		//print the data
		cout << TheRecipeVector[i].getChefName() << " " << RecipeNameTemp << " price : " << RecipePriceTemp << " " << "\n";
	}
}

// Function : In Menu Item, from RecipeId, return the Recipe Name
// Type	: Support Function
// PIC : Archie
// Status : Complete
string ShowFindUpdate::MenuItemRec_IdToName(vector<Menu_item> TheMIVector, int ComparedRecipeData)
{
	for(int i = 0; i < TheMIVector.size();i++)
	{
		if (TheMIVector[i].getRecipeId() ==ComparedRecipeData) //if equal, return the Name
		{
			return TheMIVector[i].getMenuName();
		}
	}
	return ""; //if no equal, return blank string
}

// Function : In Menu Item, from RecipeId, return the Recipe Price
// Type	: Support Function
// PIC : Archie
// Status : Complete
double ShowFindUpdate::MenuItemRec_IdToPrice(vector<Menu_item> TheMIVector, int ComparedRecipeData)
{
	for(int i = 0; i < TheMIVector.size();i++)
	{
		if (TheMIVector[i].getRecipeId() ==ComparedRecipeData) //if equal, return the Name
		{
			return TheMIVector[i].getprice();
		}
	}
	return 0; //if no equal, return zero
}



// Function : 2b.Display total sales for a given server
// Type	: Main Function
// PIC : Archie
// Status : Complete
void ShowFindUpdate::TotalServer(vector<Order> ordersVector, vector<Order_Item> order_itemsVector, vector<Menu_item> menu_itemsVector, int server_id) //2b. Display total sales for a given server
{
	double totalsales = 0; //variable to hold total sales for a given server
	//iterate the orders vector. Proces the order id for a match server_id
	for(int i = 0; i < ordersVector.size();i++)
	{
		if (ordersVector[i].getServerId() == server_id) //server_id match, process it
		{
			//get the sales number for this order
			int orderID = ordersVector[i].getOrderId(); //the current order ID processed

			//iterate the order_item vector 1 orderID had more than 1 Menu_item associated
			for(int i = 0; i < order_itemsVector.size();i++)
			{
				if (order_itemsVector[i].getOrderId() ==orderID) //if equal, return the Quantity
				{
					int quantity = order_itemsVector[i].getQuantity();
					int menuID = order_itemsVector[i].getMenuItemID();
					double price = MenuItemMenu_IdToPrice(menu_itemsVector,menuID);
					totalsales += (quantity * price); //add the current sales
				}
			}
		}
	}
	cout << "Total sales by server " << server_id << " : " <<totalsales<<"\n";
}



// Function : 2b.Display total sales for a given table
// Type	: Main Function
// PIC : Rico
// Status : Complete
void ShowFindUpdate::TotalTables(vector<Order> ordersVector, vector<Order_Item> order_itemsVector, vector<Menu_item> menu_itemsVector, int table_id) //2b. Display total sales for a given table
{
	double totalsales = 0; //variable to hold total sales for a given table
	//iterate the orders vector. Proces the order id for a match table_id
	for(int i = 0; i < ordersVector.size();i++)
	{
		if (ordersVector[i].getTableId() == table_id) //table_id match, process it
		{
			//get the sales number for this order
			int orderID = ordersVector[i].getOrderId(); //the current order ID processed

			//iterate the order_item vector 1 orderID had more than 1 Menu_item associated
			for(int i = 0; i < order_itemsVector.size();i++)
			{
				if (order_itemsVector[i].getOrderId() ==orderID) //if equal, return the Quantity
				{
					int quantity = order_itemsVector[i].getQuantity();
					int menuID = order_itemsVector[i].getMenuItemID();
					double price = MenuItemMenu_IdToPrice(menu_itemsVector,menuID);
					totalsales += (quantity * price); //add the current sales
				}
			}
		}
	}
	cout << "Total sales by table " << table_id << " : " <<totalsales<<"\n";
}


// Function : In Order Item, from order_id, return the quantity
// Type	: Support Function
// PIC : Archie
// Status : Complete
int ShowFindUpdate::OrderItemIdToQuantity(vector<Order_Item> TheOrderItemVector, int order_Id)
{
	for(int i = 0; i < TheOrderItemVector.size();i++)
	{
		if (TheOrderItemVector[i].getOrderId() ==order_Id) //if equal, return the Quantity
		{
			return TheOrderItemVector[i].getQuantity();
		}
	}
	return 0; //if no equal, return zero
}

// Function : In Order Item, from order_id, return the menuitem_id
// Type	: Support Function
// PIC : Archie
// Status : Complete
int ShowFindUpdate::OrderItemIdToMenuID(vector<Order_Item> TheOrderItemVector, int order_Id)
{
	for(int i = 0; i < TheOrderItemVector.size();i++)
	{
		if (TheOrderItemVector[i].getOrderId() == order_Id) //if equal, return the Quantity
		{
			return TheOrderItemVector[i].getMenuItemID();
		}
	}
	return 0; //if no equal, return zero
}

// Function : In Menu Item, from MenuItemId, return the Recipe Price
// Type	: Support Function
// PIC : Archie
// Status : Complete
double ShowFindUpdate::MenuItemMenu_IdToPrice(vector<Menu_item> TheMIVector, int menuitemID)
{
	for(int i = 0; i < TheMIVector.size();i++)
	{
		if (TheMIVector[i].get_menu_item_id() == menuitemID) //if equal, return the Name
		{
			return TheMIVector[i].getprice();
		}
	}
	return 0; //if no equal, return zero
}

// Function : In Menu Item, from MenuItemId, return the Recipe Price
// Type	: Support Function
// PIC : Archie
// Status : Complete
string ShowFindUpdate::MenuItemMenu_IdToName(vector<Menu_item> TheMIVector, int menuitemID)
{
	for(int i = 0; i < TheMIVector.size();i++)
	{
		if (TheMIVector[i].get_menu_item_id() == menuitemID) //if equal, return the Name
		{
			return TheMIVector[i].getMenuName();
		}
	}
	return ""; //if no equal, return blank string
}


// Function : 3b.Add a new menu item using an existing recipe to an existing category
// Type	: Main Function
// PIC : Archie
// Status : Complete
void ShowFindUpdate::AddMenubyRecipe(vector<Menu_item> &TheMIVector, vector<Recipe> TheRecipeVector, int recipe_id, string category_id,string MenuName, double price)
{
	//temporary variable to construct the new MenuItem
	int MenuItemID;
	string CategoryID = category_id;
	int RecipeID = recipe_id;
	string MenuItemName = MenuName;
	double MenuItemPrice = price;
	Description MenuDescription;

	//if recipe id exist, fil the vector
	if (RecipeFillDescbyID(TheRecipeVector, RecipeID, MenuDescription))
	{
		MenuItemID = GenerateMenuItemID(TheMIVector); // generate the menuitemID
		//at this point, all data has been filled, add the new Menu_Item
		TheMIVector.push_back(Menu_item(MenuItemID,CategoryID,RecipeID,MenuItemName,MenuItemPrice,MenuDescription));//push the vector
	}
	else //not exist, show error message
	{
		cout << "The recipe id " <<RecipeID<<  " is not exist\n";
	}



}


// Function : 3b.Add a menu item to an order
// Type	: Main Function
// PIC : Rico
// Status : Complete
void ShowFindUpdate::AddItemByOrder(vector<Order_Item> ordersVector, vector<Menu_item> TheMIVector, int order_id, int menu_item_id, int item_quantity, int seat_id)
{
	//if recipe id exist, fil the vector
	if (OrderIDVerify(ordersVector,order_id))
	{
	    //ordersVector.display();
	//    cout << "this order exists";
		ordersVector.push_back(Order_Item(seat_id,order_id, menu_item_id, item_quantity));//push the vector
		cout << "This order has been updated";
	}
	else //not exist, show error message
	{
		cout << "The order id " <<order_id<<  " does not exist\n";
	}



}

// Function : Verifies the existance of an order
// Type	: Support Function
// PIC : Rico
// Status : Complete
bool ShowFindUpdate::OrderIDVerify(vector<Order_Item> ordersVector, int order_id)
{
	for(int i = 0; i < ordersVector.size();i++)
	{
		if (ordersVector[i].getOrderId() == order_id)
		{
			return true;
		}
	}
	return false; //if no equal, return false
}




// Function : In Recipe, from RecipemId, fill the description. Return true, if found, false otherwise
// Type	: Support Function
// PIC : Archie
// Status : Complete
bool ShowFindUpdate::RecipeFillDescbyID(vector<Recipe> TheRecipeVector, int RecipeID, Description &MenuDescription)
{
	for(int i = 0; i < TheRecipeVector.size();i++)
	{
		if (TheRecipeVector[i].getRecipeId() == RecipeID) //if equal, fill the data
		{
			MenuDescription.descr = TheRecipeVector[i].getInstructionsString(); //fill the description
			return true;
		}
	}
	return false; //if no equal, return false
}

// Function : Generate Menu_ItemID for the new item
// Type	: Support Function
// PIC : Archie
// Status : Complete
int ShowFindUpdate::GenerateMenuItemID(vector<Menu_item> TheMIVector)
{
	int menuIDTemp = 1; //temporary menu item
	while (CheckMenuItemID(TheMIVector,menuIDTemp)) //while exist, increment temporary number
	{
		++menuIDTemp;
	}
	return menuIDTemp;
}

// Function : Check existence of Menu_ItemID
// Type	: Support Function
// PIC : Archie
// Status : Complete
bool ShowFindUpdate::CheckMenuItemID(vector<Menu_item> TheMIVector, int MenuID)
{
	for(int i = 0; i < TheMIVector.size();i++)
	{
		if (TheMIVector[i].get_menu_item_id() == MenuID) //if equal, return true
		{
			return true;
		}
	}
	return false; //if no equal, return false
}


// Function : Print out a recipe based off it's RecipeID
// Type	: Output Function
// PIC : Rico
// Status : Complete
void ShowFindUpdate::PrintRecipe(vector<Recipe> TheRecipeVector, int RecipeID)
{
                cout << "Enter a recipe ID number\n";
            cin >> RecipeID;
	for(int i = 0; i < TheRecipeVector.size();i++)
	{
		if (TheRecipeVector[i].getRecipeId() == RecipeID) //if equal, return the Quantity
		{
            cout << TheRecipeVector[i].display();
		}
	}
}


void ShowFindUpdate::PrintMenuItemPrice(vector<Menu_item> mi_vect) //B1c print all menu items sorted by Price TTL
{
    cout << endl;
	//Menu_item::Menu_item temp();
	//Arrange the vector
	for(int i = 0; i<mi_vect.size();i++)
	{
	    for(int j = 0; j<mi_vect.size()-(i+1);j++)
	    {
	        if(mi_vect[j].get_price()<mi_vect[j+1].Menu_item::get_price())
	        {
	            Menu_item temp(mi_vect[j+1]);
	            mi_vect[j+1].copy(mi_vect[j]);
	            mi_vect[j].copy(temp);
	        }
	    }
	}

	//print the vector
	for(int i = 0; i < mi_vect.size();i++)
	{
		cout << "\nItem Name: " << mi_vect[i].Menu_item::get_menu_item_name() << endl;
		cout << "Price: " << mi_vect[i].Menu_item::get_price() << endl;
		cout << "Description: " << mi_vect[i].Menu_item::get_descr_string() << endl;
	}

}

void ShowFindUpdate::FindMenuItemPrice(int itemID, vector<Menu_item> menu_items, vector<Order_Item> order_items)
{
	double item_price = -1;
	int order_total = 0;
	string item_name = "";
	cout << itemID;
	for(int i = 0; i<menu_items.size(); i++)
	{
		if(itemID == menu_items[i].get_menu_item_id())
		{
			item_price = menu_items[i].get_price();
			item_name = menu_items[i].get_menu_item_name();
		}
	}
	if(item_price == -1)
	{
		cout << "\n\nERROR: Invalid Menu ID.\n\n";
		return;
	}

	for(int i = 0; i<order_items.size(); i++)
	{
		if(itemID == order_items[i].getMenuItemID())
		{
			order_total += order_items[i].getQuantity();
		}
	}

	cout << "\nThe total sales for Menu Item ID " << itemID << " called " << item_name << " (priced at $" << setprecision(2) << item_price << ") is:";
	cout << "\n\tQuantity Ordered: " << order_total;
	cout << "\n\tTotal Sales: $" << order_total * (double)item_price << endl;

}
